# 导入相关库和模块
from contextlib import contextmanager
from typing import Union, Dict, List, Any
from database import SessionLocal
import sys
from typing import List
from config.logging import logger
from models.permission import Permission, PermissionSchema
from models.admin_menu import AdminMenu, AdminMenuSchema

from services.database_manager import databaseManager


# 定义服务类
class UserPermissionApiService:
    def __init__(self, db):
        self.db = db
        self.db_manager = databaseManager(self.db)

    async def list_user_permissions(self, page, limit, name=None) -> Dict[str, Union[List[Any], Any]]:
        query = self.db.query(Permission).filter(Permission.parent_id.is_(None))
        if name:
            query = query.filter(Permission.name.contains(name))
        lists = self.db_manager.paginate_query(query, page, limit)

        # 递归地构建每个权限的子权限树
        def build_permission_tree(permission):
            per_dict = PermissionSchema(**permission.to_dict()).dict()
            per_dict['children'] = [build_permission_tree(child) for child in (permission.children or [])]

            return per_dict

        data =  [build_permission_tree(per) for per in lists] if lists else []
        return {"list": self.db_manager.convert_dict_keys(data), "total": query.count()}

    async def create_user_permission(self, data):
        # 检测是否存在相同的名字
        data = self.db_manager.snake_convert_dict_keys(data)
        if self.db_manager.detail_query(Permission, {"name": data["name"]}) is not None:
            return {"error": "名称已存在"}

        # 创建权限时包含父权限
        permission_data = {
            "name": data["name"],
            "description": data["desc"]
        }
        if "parent_id" in data and data["parent_id"] is not None:
            # 验证 parent_id 是否指向有效的权限
            if self.db_manager.detail_query(Permission, {"id": data["parent_id"]}) is None:
                return {"error": "指定的父权限不存在"}
            permission_data["parent_id"] = data["parent_id"]
        info = self.db_manager.create_entry(Permission, permission_data)

        return info

    async def update_user_permission(self, data, pid):
        # 检查要更新的权限是否存在
        permission = self.db_manager.detail_query(Permission, {"id": pid})
        if permission is None:
            return {"error": "权限不存在"}

        # 准备更新的数据
        update_data = {"name": data["name"], "description": data["desc"]}
        # 如果提供了 parent_id，更新 parent_id
        if "parent_id" in data and data["parent_id"] is not None:
            # 可能还需要检查新的 parent_id 是否有效或是否会导致循环引用
            update_data["parent_id"] = data["parent_id"]

        # 执行更新操作
        self.db_manager.detail_update(Permission, {"id": pid}, update_data)
        return True

    async def delete_user_permission(self, pid):
        # 删除权限
        self.db_manager.delete_records_by_ids(Permission, pid)
        return True

    async def detail_user_permission(self, pid):
        detail = self.db_manager.detail_query(Permission, {"id": pid})
        if detail is None:
            return {"error": "内容不存在"}
        parent_id = detail.get('parent_id')
        if parent_id:
            parent = self.db_manager.detail_query(Permission, {"id": parent_id})
            detail['parent'] = parent

            # 获取子权限列表
        children = self.db_manager.list_query(Permission, {"parent_id": pid})
        detail['children'] = children

        return self.db_manager.convert_dict_keys(detail)

    async def update_permission_menu(self, menuId, permissionIds):
        """
        菜单与权限绑定
        """
        menu_info = self.db.query(AdminMenu).filter(AdminMenu.id == menuId).first()
        logger.info(f"打印结果{type(menu_info)},{menu_info}")
        if menu_info is None:
            return {'error': "菜单不存在"}
        permission = self.db.query(Permission).filter(Permission.id.in_(permissionIds)).all()
        if permission is None:
            return {'error': "权限不存在"}
        menu_info.permissions.extend(permission)
        self.db.commit()
        self.db.refresh(menu_info)
        menu_info_schema = AdminMenuSchema.from_orm(menu_info)
        return self.db_manager.convert_dict_keys(menu_info_schema.dict())

